package com.github.wujichen158.andemusic.newcommands;

import com.github.wujichen158.andemusic.aboutconfig.AndeMusicConfig;
import com.github.wujichen158.andemusic.network.MusicMessage;
import com.github.wujichen158.andemusic.network.AndeMusicNetwork;
import com.github.wujichen158.andemusic.playernbt.MusicTypeProvider;
import com.google.common.collect.Lists;
import net.minecraft.client.resources.I18n;
import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.command.WrongUsageException;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextFormatting;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Optional;

public class SetMusicCommand extends CommandsRoot {
    @Nonnull
    @Override
    public String getName() {
        return "setmusic";
    }

    @Override
    public String getUsage(ICommandSender sender) {
        return I18n.format("commands.set.usage");
    }

    @Override
    public void execute(@Nonnull MinecraftServer server, @Nonnull ICommandSender sender, String[] args) throws CommandException {
        String playerName;
        if (args.length == 2) {
            changeMusic(args[0], args[1], sender, null, null, server);
        } else if (args.length == 1) {
            playerName = sender.getName();
            changeMusic(playerName, args[0], sender, null, null, server);
        } else if (args.length == 3) {
            playerName = sender.getName();
            changeMusic(playerName, args[0], sender, args[1], args[2], server);
        } else if (args.length == 4) {
            changeMusic(args[0], args[1], sender, args[2], args[3], server);
        } else {
            send(sender, TextFormatting.YELLOW, "commands.set.usage");
        }
    }

    @Nonnull
    @Override
    public List<String> getTabCompletions(@Nonnull MinecraftServer server, @Nonnull ICommandSender sender, String[] args, @Nullable BlockPos pos) {
        if (args.length == 1) {
            String[] names = server.getOnlinePlayerNames();
            return CommandBase.getListOfStringsMatchingLastWord(args, names);
        }
        return Lists.newArrayList();
    }

    public static void changeMusic(String playerName, String musicType, ICommandSender sender, String minTime, String maxTime,
                             MinecraftServer server) throws WrongUsageException {
        try {
            EntityPlayerMP player = getPlayer(server, sender, playerName);

            Optional.ofNullable(MusicTypeProvider.get(player)).ifPresent(nbt -> {
                nbt.setMusicType(musicType);

                int[] delayTimes = tryGetDelayTimes(minTime, maxTime);
                int rMin = delayTimes[0];
                int rMax = delayTimes[1];

                nbt.setMinDelayTime(rMin);
                nbt.setMaxDelayTime(rMax);

                AndeMusicNetwork.INSTANCE.sendTo(new MusicMessage(musicType, rMin, rMax), player);
                send(sender, TextFormatting.GREEN, "commands.set.success", player.getDisplayName(),
                        musicType, rMin, rMax);
            });
        } catch (Exception e) {
            throw new WrongUsageException("commands.set.usage");
        }
    }

    public static int[] tryGetDelayTimes(String minTime, String maxTime) {
        // If no min delay time presented, use the default val in config
        int rMin = Optional.ofNullable(minTime).map(Integer::parseInt).orElse(AndeMusicConfig.minWaitTime);

        // If no max delay time presented, use the default val in config
        int rMax = Optional.ofNullable(maxTime).map(Integer::parseInt).orElse(AndeMusicConfig.maxWaitTime);

        // Swap if not in order
        if (rMin > rMax) {
            int temp = rMax;
            rMax = rMin;
            rMin = temp;
        }

        return new int[]{rMin, rMax};
    }

}
